package ma.xin.shi.table;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Shell;
import ma.xin.shi.common.MultiSelectDialog;

import java.util.List;

public class TableManager {
    public static void setupEditableTable(Table table, EditableTableConfig config) {
        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseDoubleClick(MouseEvent e) {
                Point pt = new Point(e.x, e.y);
                int column = -1;
                int x = pt.x;
                int currentX = 0;
                TableColumn[] columns = table.getColumns();

                for (int i = 0; i < columns.length; i++) {
                    int width = columns[i].getWidth();
                    if (x >= currentX && x <= currentX + width) {
                        column = i;
                        break;
                    }
                    currentX += width;
                }

                TableItem item = table.getItem(pt);
                if (item != null && column != -1) {
                    editTableCell(table, item, column, config);
                }
            }
        });
    }

    private static void editTableCell(final Table table, final TableItem item, final int column, final EditableTableConfig config) {
        Object data = item.getData();
        if (data instanceof Control) {
            Control oldEditor = (Control) data;
            oldEditor.dispose();
        }

        final TableEditor editor = new TableEditor(table);
        editor.grabHorizontal = true;

        /* Decide whether to use a dropdown box based on the configuration. */
        if (config.isComboColumn(column)) {
            // current col is Combo type
            final Combo combo = new Combo(table, SWT.DROP_DOWN | SWT.READ_ONLY);
            String[] items = config.getComboItems(column);
            if (items != null) {
                combo.setItems(items);
                combo.setText(item.getText(column)); // Set current value
            } else {
                combo.add("No options");
            }

            // Save the current editing control to the item.
            item.setData(combo);

            combo.addFocusListener(new FocusAdapter() {
                @Override
                public void focusLost(FocusEvent e) {
                    item.setText(column, combo.getText());
                    combo.dispose();
                    editor.dispose();
                    item.setData(null);
                }
            });

            combo.addKeyListener(new KeyAdapter() {
                @Override
                public void keyReleased(KeyEvent e) {
                    if (e.character == SWT.CR || e.character == SWT.KEYPAD_CR) {
                        item.setText(column, combo.getText());
                        combo.dispose();
                        editor.dispose();
                        item.setData(null);
                    }
                }
            });

            editor.setEditor(combo, item, column);
            combo.setFocus();

        } else if (config.isMultiSelectColumn(column)) {
            String[] availableOptions = config.getMultiSelectItems(column);
            String[] currentSelections = item.getText(column).split(", ");

            Shell parentShell = table.getShell();
            List<String> selected = MultiSelectDialog.show(
                parentShell,
                "选择配置项",
                availableOptions,
                currentSelections
            );

            if (!selected.isEmpty()) {
                item.setText(column, String.join(", ", selected));
            }
        } else {
            // current col is text type
            final Text text = new Text(table, SWT.NONE);
            text.setText(item.getText(column));
            text.selectAll();

            // Save the current editing control to the item.
            item.setData(text);

            text.addFocusListener(new FocusAdapter() {
                @Override
                public void focusLost(FocusEvent e) {
                    item.setText(column, text.getText());
                    text.dispose();
                    editor.dispose();
                    item.setData(null);
                }
            });

            text.addKeyListener(new KeyAdapter() {
                @Override
                public void keyReleased(KeyEvent e) {
                    if (e.character == SWT.CR || e.character == SWT.KEYPAD_CR) {
                        item.setText(column, text.getText());
                        text.dispose();
                        editor.dispose();
                        item.setData(null);
                    }
                }
            });

            editor.setEditor(text, item, column);
            text.setFocus();
        }
    }

    /**
     * Interface: Used to configure which columns are dropdowns (currently not in use)
     */
    public interface EditableTableConfig {
        boolean isComboColumn(int columnIndex);
        String[] getComboItems(int columnIndex);

        // 用于判断是否是多选列（Java 8+ 默认方法）
        default boolean isMultiSelectColumn(int columnIndex) {
            return false;
        }

        // 新增方法：返回该列的多选选项
        default String[] getMultiSelectItems(int columnIndex) {
            return new String[0];
        }

        // 新增单元格是否可编辑控制
        default boolean isCellEditable(int columnIndex, int rowIndex) {
            return true;
        }

    }
    
    /* Methods for printing tables and column widths (reserved) */
    public static void printTableAndColumnWidths(Table table) {
        Rectangle bounds = table.getBounds(); // Obtain the actual size of the table
        int totalColumnWidth = 0;
        TableColumn[] columns = table.getColumns();

        System.out.printf("table name: %s%n", table.getData() != null ? table.getData().toString() : "unamed");
        System.out.printf("table width: %d%n", bounds.width);

        for (int i = 0; i < columns.length; i++) {
            int width = columns[i].getWidth();
            totalColumnWidth += width;
            System.out.printf("  col %d width: %d%n", i, width);
        }

        System.out.printf("The sum of all column widths: %d%n", totalColumnWidth);
        System.out.printf("Width difference (table - column total): %d%n", bounds.width - totalColumnWidth);
        System.out.println("----------------------------");
    }

    /* Print the total width of the table and the total width of the columns. */
    public static void printTableTotalWidth(Table table) {
        Rectangle bounds = table.getBounds();
        int totalColumnWidth = 0;
        for (TableColumn column : table.getColumns()) {
            totalColumnWidth += column.getWidth();
        }
        System.out.println("Final table width: " + bounds.width + " | Sum of column widths: " + totalColumnWidth);
    }

    public static void renumberTableItems(Table table) {
        for (int i = 0; i < table.getItemCount(); i++) {
            TableItem item = table.getItem(i);
            item.setText(0, String.valueOf(i));
        }
    }

    /**
     * 向表格中添加指定数量的空行
     */
    public static void addEmptyRowsToTable(Table table, int rowCount) {
        for (int i = 0; i < rowCount; i++) {
            TableItem item = new TableItem(table, SWT.NONE);
            for (int j = 0; j < table.getColumnCount(); j++) {
                item.setText(j, "");  // 所有单元格为空字符串
            }
        }
    }
}
